#include "ws2812.h"
 
//显存数组，长度为 灯的数量*24+复位周期
uint16_t WS2812_RGB_Buff[LED_NUM*DATA_LEN+WS2812_RST_NUM] = {0}; 
 
/**
 * 函数：WS2812单灯设置函数
 * 参数：num:灯的位置，R、G、B分别为三个颜色通道的亮度，最大值为255
 * 作用：单独设置每一个WS2812的颜色
***/
void WS2812_Set(uint16_t num,uint8_t R,uint8_t G,uint8_t B)
{
  uint32_t indexx=(num*(3*8));
  for (uint8_t i = 0;i < 8;i++)
  {
	//填充数组
	WS2812_RGB_Buff[indexx+i]      = (G << i) & (0x80)?WS_H:WS_L;
	WS2812_RGB_Buff[indexx+i + 8]  = (R << i) & (0x80)?WS_H:WS_L;
	WS2812_RGB_Buff[indexx+i + 16] = (B << i) & (0x80)?WS_H:WS_L;
  }
}
void WS2812_Set_ALL(uint8_t R,uint8_t G,uint8_t B)
{
	WS2812_Set(0,R,G,B);
	WS2812_Set(1,R,G,B);
	WS2812_Set(2,R,G,B);
	WS2812_Set(3,R,G,B);
	WS2812_Set(4,R,G,B);
	WS2812_Set(5,R,G,B);
	WS2812_Set(6,R,G,B);
	WS2812_Set(7,R,G,B);
	WS2812_Set(8,R,G,B);
	WS2812_Set(9,R,G,B);
	WS2812_Set(10,R,G,B);
	WS2812_Set(11,R,G,B);
	WS2812_Set(12,R,G,B);
	WS2812_Set(13,R,G,B);
	WS2812_Set(14,R,G,B);
	WS2812_Set(15,R,G,B);

}
 
//WS2812初始化函数
void WS2812_Init()
{
	//设置关闭所有灯
  for(int i=0;i<16;i++)
  {
	WS2812_Set(i,0,0,0);
  }
  //作用：调用DMA将显存中的内容实时搬运至定时器的比较寄存器
  HAL_TIM_PWM_Start_DMA(&htim2,TIM_CHANNEL_1,(uint32_t *)WS2812_RGB_Buff,sizeof(WS2812_RGB_Buff)/sizeof(uint16_t)); 
}
void WS2812_Clear()
{

  for(int i=0;i<16;i++)
  {
	WS2812_Set(i,0,0,0);
  }

}

uint16_t time=0;
#define FUNCBLOCK 100

uint8_t PM_Func(uint8_t channel)
{
	static uint8_t Funcout=0;
	
	switch(channel)
	{
		case R:
			time++;
			if(time<FUNCBLOCK)
			{Funcout=FUNCBLOCK-time;}
			else if(time>=2*FUNCBLOCK)
			{Funcout=time-2*FUNCBLOCK;}
			else
			{Funcout=0;}
			break;
		case G:

			if(time<FUNCBLOCK)
			{Funcout=(uint8_t)time;}
			else if(time>=2*FUNCBLOCK)
			{Funcout=0;}
			else
			{Funcout=2*FUNCBLOCK-time;}
			break;
		case B:

			if(time<FUNCBLOCK)
			{Funcout=0;}
			else if(time>=2*FUNCBLOCK)
			{Funcout=3*FUNCBLOCK-time;}
			else
			{Funcout=time-FUNCBLOCK;}
			break;
	
	
	}
	if(time>=3*FUNCBLOCK)
	{
	time=0;
	}
	return Funcout;


}

uint8_t k=1;
uint8_t Lingtning=100;
#define LOOPTIME 100
uint8_t RainbolFunc(RB_Buff *RB,uint16_t fri)
{
	RB->time+=1;
	switch(RB->sta)
{
		case 0:
			if(RB->time>fri){RB->sta=1;RB->time=0;}
			
			break;
		case 1:
			RB->sum=k*(RB->time);
			if(RB->sum==Lingtning){RB->time_last=RB->time;RB->sta=2;}
			break;
			
		case 2:
			RB->sum=Lingtning;
		if(RB->time-RB->time_last>200){RB->time_last=RB->time;RB->sta=3;}
			break;
		
		case 3:
			RB->sum=Lingtning-k*(RB->time-RB->time_last);
			if(RB->sum==0){RB->sta=4;RB->time=0;}
			break;
			
		case 4:
			if(RB->time>LOOPTIME){RB->sta=1;RB->time=0;}
			
			break;



}


return RB->sum;
}

